import java.awt.*;
import java.util.*;

/**
 * 
 * Nos permite generar la solucion y dibujarla en pantalla
 *
 */

public class Pizarra extends Panel {

	private static final long serialVersionUID = 1L;
	private static final int border = 5;
	private static final int base = 3;
	private Vector<Piezas> _Figuras;
	private int _Tam;
	private int _eje;
	private int _center;
	
	public Pizarra(){
		super(new FlowLayout(FlowLayout.CENTER));
		this.setBackground(Color.WHITE);
	}
	
	public Pizarra(int Tam,int base,int align) {
		super(new FlowLayout(FlowLayout.CENTER));
		this.setBackground(Color.WHITE);
		_Figuras = new Vector<Piezas>();
		this._Tam = Tam;
		this._eje = base;
		this._center = align;
	}
	
	public Pizarra(Pizarra x){
		this._Tam = x.get_tam();
		this._eje = x.get_eje();
		this._center = x.get_center();
	}
	
	/**
	 * Generar Solucion
	 * Se trata de una heuristica de colocacion de paquetes basada en un jerarquia de niveles
	 * de tal forma que el primer paquete marca el nivel de los siguientes hasta que se encuentre
	 * un paquete de mayor jerarquia (Altura) o se quede sin espacio, en tal caso se crea un nuevo nivel.
	 * 
	 * Existe una rotacion que consiste en que cada nuevo nivel el primer paquete entra acostado y los sucesivos
	 * se comprueba si entran con la cara mas ancha en vertical, en caso contrario se introducen como quepan pero si
	 * es asi se rota para que deje mayor espacio para los sucesivos paquetes.
	 * 
	 * @param x
	 * Vector de piezas a introducir en el contenedor
	 * 
	 * @return
	 * Altura obtenida
	 */
	
	public int Generar_Solucion(Vector<Piezas> x) {
		_Figuras = x;
		Vector<Nivel> niveles = new Vector<Nivel>();
		
		for (int i = 0; i < _Figuras.size();i++) {
			int j = 0;
			
			while (!Cabe(_Figuras.get(i),niveles,j))
				j++;
			
			if (j>=niveles.size()) {
				Nivel nuevo = new Nivel();
				
				if (_Figuras.get(i).get_h() > _Figuras.get(i).get_w())
					_Figuras.get(i).rotate();
				
				nuevo.set_superior(niveles.get(j-1).get_superior() - _Figuras.get(i).get_h());
				nuevo.set_inferior(niveles.get(j-1).get_superior());
				nuevo.set_ancho(_Figuras.get(i).get_w());
				niveles.add(nuevo);
			}
			
			_Figuras.get(i).set_py(niveles.get(j).get_inferior() - _Figuras.get(i).get_h());
			_Figuras.get(i).set_px(niveles.get(j).get_ancho() - _Figuras.get(i).get_w());
		}
		
		return get_eje() - niveles.get(niveles.size() - 1).get_superior();
	}
	
	public boolean Cabe(Piezas p,Vector<Nivel> nivel,int j) {
		
		if (nivel.isEmpty()) {
			Nivel x = new Nivel();
			
			if (p.get_h() > p.get_w())
				p.rotate();
			
			x.set_superior(get_eje() - p.get_h());
			x.set_inferior(get_eje());
			x.set_ancho(p.get_w());
			nivel.add(x);
			
			return true;
		}
		else {
			if (j >= nivel.size())
				return true;
			
			if ((((nivel.get(j).get_inferior() - nivel.get(j).get_superior()) >= p.get_w())) && ((this.get_tam() - nivel.get(j).get_ancho() >= p.get_h()))) {
				p.rotate();
				nivel.get(j).set_ancho(nivel.get(j).get_ancho() + p.get_w());
				return true;
			}
			
			if ((((nivel.get(j).get_inferior() - nivel.get(j).get_superior()) >= p.get_h())) && ((this.get_tam() - nivel.get(j).get_ancho() >= p.get_w()))) {
				nivel.get(j).set_ancho(nivel.get(j).get_ancho() + p.get_w());
				return true;
			}
	
		}
		
		return false;
	}
	
	/**
	 * Funcion que pinta los rectangulos en pantalla
	 */
	
	public void paint(Graphics e) {
		Font fuente = new Font("Courier", Font.BOLD, 12);
		e.setColor(Color.black);
		e.fillRect(get_center() - border, 0, border,get_eje() + base);
		e.drawRect(get_center() - border, 0, border, get_eje() + base);
		
		e.fillRect(get_center() + get_tam(),0, border,get_eje() + base);
		e.drawRect(get_center() + get_tam(),0, border, get_eje() + base);
		
		e.translate(get_center(), 0);
		e.setColor(Color.black);
		e.fillRect(0, get_eje(), get_tam(),base);
		e.drawRect(0, get_eje(), get_tam(),base);
		
		
		for (int i = 0; i < _Figuras.size(); i++) {
			
			e.setColor(_Figuras.get(i).get_color());
			e.fillRect(_Figuras.get(i).get_px(),_Figuras.get(i).get_py(), _Figuras.get(i).get_w(), _Figuras.get(i).get_h());
			
			e.setColor(Color.black);
			e.drawRect(_Figuras.get(i).get_px(),_Figuras.get(i).get_py(), _Figuras.get(i).get_w(), _Figuras.get(i).get_h());
			
			e.setFont(fuente);
		    e.drawString(String.valueOf(i), (_Figuras.get(i).get_px() + (_Figuras.get(i).get_w() / 2)) - 1, (_Figuras.get(i).get_py() + (_Figuras.get(i).get_h() / 2)) - 1);
		}
	}
	
	/**
	 * 
	 * Mutadores e inspectores
	 */
	
	public int get_tam() {
		return _Tam;
	}
	
	public int get_eje() {
		return _eje;
	}
	
	public int get_center() {
		return _center;
	}
	
	public void set_Figuras(Vector<Piezas> x) {
		_Figuras = x;
	}
	
	public void set_tam(int x) {
		_Tam = x;
	}
	
	public void set_eje(int x) {
		_eje = x;
	}
	
	public void set_center(int x) {
		_center = x;
	}
	
	public Vector<Piezas> get_figuras(){
		return _Figuras;
	}
	
}
